/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-1-4 21:53:17
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#ifndef INCLUDE_NET_NETINSIDE_NET_REACTOR_IMPL_H_
#define INCLUDE_NET_NETINSIDE_NET_REACTOR_IMPL_H_

#include "base/xthread.h"
#include "net/netbasedefine.h"
#include "NRSocket.h"
#include <vector>
#include <sys/epoll.h>

#define EPOLL_MAX_FD_SIZE         60000
#define EPOLL_RESERVED_FD_SIZE    1024

#define SOCK_BUFFER_SIZE          64*1024

class IEvent_handler;
class net_reactor_impl_t
{
public:
	net_reactor_impl_t();
	virtual ~net_reactor_impl_t();
public:
	int init_reactor( IEvent_handler* pHandler, int threadnum );
	int uninit_reactor();

	SOCK_FD open_tcp_server( const char* local_ip, int local_port );
	SOCK_FD open_tcp_client( const char* remote_ip, int remote_port );
	SOCK_FD open_udp_endpoint( const char* local_ip, int local_port );

	int send( SOCK_FD fd, const char* data, int len );
	int sendto( SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port );
	int close_fd( SOCK_FD fd );

protected:
	int running_task( smart::threadbase_t* thr );
	void set_destroy_status( bool status );

	int deal_pending_close_fdQ();
	int deal_pending_destroy();

	int do_accept( SOCK_FD listen_fd );
	int do_recv( SOCK_FD fd, const char*ip, int port );
	int do_recvfrom( SOCK_FD fd );
	int do_send( SOCK_FD fd, const char* data, int len, int& send_len );
	int do_sendto( SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port, int& send_len );
	int do_close( SOCK_FD fd, int err );

protected:
	int add_conn_bean(NRSocket* bean);
	int del_conn_bean(SOCK_FD fd);
	int del_all_conn_bean();
	smart::ref_ptr<NRSocket> get_conn_bean(SOCK_FD fd);

	int add_listen_bean(NRSocket* bean);
	int del_listen_bean(SOCK_FD fd);
	int del_all_listen_bean();
	smart::ref_ptr<NRSocket> get_listen_bean(SOCK_FD fd);
	bool is_listen_bean(SOCK_FD fd);
protected:
	IEvent_handler* m_pHandler;

	std::map<int, smart::threadbase_t*> m_thread_pool;
	smart::mutex_t m_thread_pool_mtx;

	NetConnMap m_conn_map; //all tcp-connections or udp-endpoints
	smart::mutex_t m_mtx_conn_map;

	NetListenMap m_listen_map; //all listen fd for multi-services
	smart::mutex_t m_mtx_listen_map;


	std::map<SOCK_FD, int> m_pending_close_fd_map; //sockfd --> close's errcode; for on_close
	smart::mutex_t m_mtx_pending_close;

	bool m_pending_destroy;   //user destroy reactor [for thread busy wait]
	smart::mutex_t m_mtx_pending_destroy;


	typedef struct epoll_event epoll_event_t;
	int m_epfd; //epoll fd
	epoll_event_t* m_ep_events; //epoll event set(epoll_wait active socket)
    int m_evt_idx;
    int m_evt_total;
};

#endif //~INCLUDE_NET_NETINSIDE_NET_REACTOR_IMPL_H_
